﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace uz.control
{
    public partial class AutoComplateWindows : Form
    {
        public AutoComplateWindows()
        {
            InitializeComponent();

            ComplateText = new ComplateTextHandle(MyComplateText);
        }

        public delegate WordIndex GetWordsHandle(KeyEventArgs e);

        public GetWordsHandle GetWords = null;

        public delegate void ComplateTextHandle(TextBox txt, Word word);
        public ComplateTextHandle ComplateText = null;

        public void MyComplateText(TextBox txt, Word word)
        {
            txt.Text = word.Text;
            txt.SelectionStart = word.Text.Length;
        }

        private void AutoComplateWindows_MouseDown(object sender, MouseEventArgs e)
        {
            this.Hide();
        }


        public  TextBox TextControl { get; set; }
        public  WordIndex Words { get; set; }
        public  bool IsAutoComplate { get; set; }

        public  void OpenAutoComplate(TextBox txt, WordIndex wi)
        {
            TextControl = txt;
            Words = wi;
            IsAutoComplate = true;
        }

        private  List<Word> lstWord = null;

        public  void ProcessKeyUp(KeyEventArgs e)
        {
            if (IsAutoComplate == false)
            {
                return;
            }

            Form frm = TextControl.FindForm();

            if (frm == null)
            {
                return;
            }

            if (e.KeyCode == Keys.Space 
                || e.KeyCode == Keys.Enter 
                || e.KeyCode == Keys.Up
                || e.KeyCode == Keys.Down
                || e.KeyCode == Keys.PageDown
                || e.KeyCode == Keys.PageUp
                || e.KeyCode == Keys.Tab
            )
            {
                return;
            }

            Rectangle rect = frm.RectangleToScreen(TextControl.Bounds);


            string sch = GetSearchString();
            Console.WriteLine(sch);

            List<string> lst = new List<string>();
            if(sch.Length !=0)
            {
                if (GetWords != null)
                {
                    Words = GetWords(e);
                }

                lst = Words.GetWordIdList(sch);
            }

            if (lst.Count == 0)
            {
                Hide();
                CurrentTopIdx = 0;
                SelectedIdx = -1;
            }
            else
            {
                Show();
                lstWord = Words.GetWordList(lst);
                Refresh();
            }

            int idx = TextControl.SelectionStart - sch.Length;

            if (idx < 0)
            {
                idx = 0;
            }

            Left = rect.Left + GetOffset(idx); ;
            Top = rect.Bottom;

            TextControl.FindForm().Activate();
            TextControl.Select();
        }

        public  int GetOffset(int idx)
        {
            string str = TextControl.Text.Substring(0,idx);

            Graphics g = TextControl.CreateGraphics();

            SizeF size = g.MeasureString(str, TextControl.Font);
            g.Dispose();

            return (int)size.Width;
        }

        private int GetCurrentWordStart()
        {
            string str = "";

            str = TextControl.Text.Substring(0, TextControl.SelectionStart);

            string strChar = "";
            int idx = 0;
            for (idx = str.Length - 1; idx >= 0; idx--)
            {
                strChar = str.Substring(idx, 1);

                if (" \t\r\n".IndexOf(strChar) != -1)
                {
                    idx++;
                    break;
                }

            }

            if (idx < 0)
            {
                idx = 0;
            }

            return idx;
        }

        private string GetSearchString()
        {
            int idx = GetCurrentWordStart();
            string str = TextControl.Text.Substring(idx, TextControl.SelectionStart - idx);

            return str.Trim();
        }

        public  bool ProcessCmdKey(Keys key)
        {
            if (IsAutoComplate == false)
            {
                return false;
            }

            if (Visible == false)
            {
                return false;
            }

            if (key == Keys.Down)
            {
                if (SelectedIdx == 9)
                {
                    SelectedIdx = 0;
                    CurrentTopIdx += 10;
                }else if (SelectedIdx + CurrentTopIdx < lstWord.Count - 1)
                {
                    SelectedIdx++;
                }

                Refresh();
                return true;
            }
            else if (key == Keys.Up)
            {
                if (SelectedIdx == 0 && CurrentTopIdx == 0)
                {
                    return true;
                }

                if (SelectedIdx == 0)
                {
                    SelectedIdx = 9;
                    CurrentTopIdx -= 10;
                }
                else
                {
                    SelectedIdx--;
                }

                Refresh();
                return true;
            }
            else if (key == Keys.PageUp)
            {
                CurrentTopIdx = Math.Max(0, CurrentTopIdx - 10);
                SelectedIdx = Math.Min(9,  lstWord.Count - CurrentTopIdx -1);
                Refresh();
                return true;
            }
            else if (key == Keys.PageDown)
            {
                int page = 0;
                if (lstWord.Count % 10 == 0)
                {
                    page = lstWord.Count / 10 - 1;
                }
                else
                {
                    page = lstWord.Count / 10 ;
                }
                CurrentTopIdx = Math.Min(page * 10, CurrentTopIdx + 10);
                SelectedIdx = 0;
                Refresh();
                return true;
            }
            else if (key == Keys.Enter || key == Keys.Space)
            {

                if (SelectedIdx == -1)
                {
                    return false;
                }
                TextControl.Clear();
                Word word = lstWord[CurrentTopIdx + SelectedIdx];
                ComplateText(TextControl, word);
                Visible = false;
                return true;
            }

            return false;

            
        }

        public  void HideAutoComplate()
        {
            IsAutoComplate = false;
            Hide();
            CurrentTopIdx = 0;
            SelectedIdx = -1;
        }

        private  int _CurrentTopIdx = 0;

        public  int CurrentTopIdx
        {
            get { return _CurrentTopIdx; }
            set { _CurrentTopIdx = value; }
        }
        private  int _SelectedIdx = -1;

        public  int SelectedIdx
        {
            get { return _SelectedIdx; }
            set { _SelectedIdx = value; }
        }


        private SizeF GetItemSize(Graphics g)
        {
            SizeF sizeRst = new SizeF();
            SizeF sizeTmp = new SizeF();

            for (int i = 0; i < 10; i++)
            {
                if (CurrentTopIdx + i >= lstWord.Count)
                {
                    break;
                }
                sizeTmp = g.MeasureString(lstWord[CurrentTopIdx + i].DisplayText,Font);

                sizeRst.Width = Math.Max(sizeRst.Width, sizeTmp.Width);
            }
            sizeRst.Height = sizeTmp.Height;

            return sizeRst;
        }

        private void AutoComplateWindows_Paint(object sender, PaintEventArgs e)
        {
            e.Graphics.FillRectangle(Brushes.WhiteSmoke, Bounds);

            SizeF size = GetItemSize(e.Graphics);

            this.Width = (int)size.Width + 1;
            this.Height = (int)size.Height * 11 + 7;

            for (int i = 0; i < 10; i++)
            {
                if (CurrentTopIdx + i >= lstWord.Count)
                {
                    break;
                }
                Word word = lstWord[CurrentTopIdx +i];

                if (i == SelectedIdx)
                {
                    e.Graphics.FillRectangle(Brushes.Blue, 0, i * size.Height, size.Width, size.Height);
                    e.Graphics.DrawString(word.DisplayText, this.Font, Brushes.WhiteSmoke, 0, i * size.Height + 2);
                }
                else
                {
                    e.Graphics.DrawString(word.DisplayText, this.Font, Brushes.Black, 0, i * size.Height + 2);
                }
            }

            string str = "dd" + "/" + "dd";

            e.Graphics.DrawString(str, this.Font, Brushes.Red, 0, 10 * size.Height + 2);

            e.Graphics.DrawRectangle(Pens.SkyBlue, 0, 0, this.ClientRectangle.Width - 1, this.ClientRectangle.Height - 1);

        }
    }
}

